package com.yf.internedstring;

import org.junit.Test;

public class StringBuilderTest {

    /*
    分析方法：
    通过jclasslib查看字节码指令，发现字符串接接的原理是调用StringBuilder的append方法
     */
    @Test
    public void test() {
        String s1 = "a";
        String s2 = "b";
        String s3 = "ab";
        String s4 = s1 + s2;

        /*
        // s1 + s2的执行细节：
        StringBuilder sb = new StringBuilder();
        sb.append(s1);
        sb.append(s2);
        sb.toString();  // 相当于new String("ab")

        // 在jdk5.0之前使用的是StringBuffer
         */

        System.out.println(s3 == s4); // false
    }


    /**
     * StringBuilder拼接字符串效率要远高于使用String的字符串拼接方式
     * 1、String字符串拼接方式会创建许多StringBuilder和String对象，浪费系统资源
     * 2、拼接过程中创建的StringBuilder和String对象会占用大量的堆空间，容易触发GC，进一步加大系统资源的耗费。
     *
     * StringBuilder的应用优化：
     * 在实际开发，如果基本确定要拼接的字符串不超过某个阈值，建议使用该阈值作为StringBuild内部数组的长度
     */
    @Test
    public void test2() {
        long start = System.currentTimeMillis();
//        joinByPlus(100000); // 5432
        joinByStringBuilder(100000); // 8
        long end = System.currentTimeMillis();
        System.out.println("花费的时间是：" + (end - start));
    }

    private void joinByPlus(int highLevel) {
        String s = "";

        for (int i = 0; i < highLevel; i++) {
            s += "a";
            /*
            // 相当于以下代码：
            StringBuilder sb = new StringBuilder();
            sb.append(s);
            sb.append("a");
            s = sb.toString(); // 创建String对象

            // 在循环体内创建了很多StringBuilder和String对象
             */
        }
    }

    private void joinByStringBuilder(int highLevel) {
//        StringBuilder sb = new StringBuilder();
        // 在实际开发，如果基本确定要拼接的字符串不超过某个阈值，建议使用该阈值作为StringBuild内部数组的长度
        StringBuilder sb = new StringBuilder(100000);

        for (int i = 0; i < highLevel; i++) {
            sb.append("a");
        }
    }
}
